;--------------------------------

!macro __DetailPrint Text
  SetDetailsPrint Both
  DetailPrint "${Text}"
  SetDetailsPrint None
!macroend

!macro __TextPrint Text
  SetDetailsPrint TextOnly
  DetailPrint "${Text}"
  SetDetailsPrint None
!macroend

!macro __ListPrint Text Data
  !define ID "${__LINE__}"
  SetDetailsPrint ListOnly

  StrCmp ${Data} "" PrintEmpty_${ID}
  DetailPrint "> ${Text}: ${Data}"
  Goto PrintDone_${ID}
  
  PrintEmpty_${ID}:
  DetailPrint "> ${Text}: Unknown"
  Goto PrintDone_${ID}

  PrintDone_${ID}:
  SetDetailsPrint None
  !undef ID
!macroend

!define DetailPrint "!insertmacro __DetailPrint"
!define TextPrint "!insertmacro __TextPrint"
!define ListPrint "!insertmacro __ListPrint"

;--------------------------------

!macro __MyAbort Text

  SetDetailsPrint Both
  Abort "${Text}"
  SetDetailsPrint None

!macroend

!define MyAbort "!insertmacro __MyAbort"

;--------------------------------

!macro __Download mode Info URL OutName
  !define ID "${__LINE__}"
  
  DL_Retry_${ID}:
  
  !if ${mode} == "popup"
    inetc::get /CAPTION "${Info}" /POPUP "${URL}" "${URL}" "${OutName}"
  !else if ${mode} == "banner"
    inetc::get /CAPTION "${Info}" /BANNER "Update Server:$\n$\n${URL}" "${URL}" "${OutName}"
  !else if ${mode} == "silent"
    inetc::get /SILENT "${URL}" "${OutName}"
  !else
    !error 'You must set MODE to "popup", "banner" or "silent"'
  !endif
  
  Pop $R0
  
  SetDetailsPrint TextOnly
  DetailPrint "Download status: $R0"
  SetDetailsPrint None

  #StrCmp $R0 "OK" DL_Success_${ID}
  #StrCmp $R0 "Cancelled" DL_Canceled_${ID}
  StrCmp $R0 "Transfer Error" DL_Error_${ID}

  Push $R0
  Goto DL_Done_${ID}

  #StrCmp $Hidden "1" DownloadFailed_${ID}
  #MessageBox MB_RETRYCANCEL|MB_ICONSTOP|MB_TOPMOST "Download failed: $R0$\nPlease check your internet connection and try again!" IDRETRY DL_Retry_${ID}
  #DownloadFailed_${ID}:
  #${MyAbort} "Update has failed."
  
  #DL_Canceled_${ID}:
  #MessageBox MB_OK|MB_ICONEXCLAMATION|MB_TOPMOST "Download was aborted by user!"
  #${MyAbort} "Update was aborted by user."
  
  DL_Error_${ID}:
  ${DetailPrint} "Transfer error detected, retrying..."
  Goto DL_Retry_${ID}

  DL_Done_${ID}:
  !undef ID
!macroend

!define Download "!insertmacro __Download"

;--------------------------------

; load language from command line /L=1033
 ; foo.exe /S /L=1033 /D=C:\Program Files\Foo
 ; or:
 ; foo.exe /S "/L=1033" /D="C:\Program Files\Foo"
 ; gpv "/L=" "1033"
 !macro __GetCLIParameterValue SWITCH DEFAULT
  !define LN "${__LINE__}"
   Push $0
   Push $1
   Push $2
   Push $3
   Push $4
 
 ;$CMDLINE='"My Setup\Setup.exe" /L=1033 /S'
   Push "$CMDLINE"
   Push '${SWITCH}"'
   !insertmacro StrStr
   Pop $0
   StrCmp "$0" "" gpv_notquoted_${LN}
 ;$0='/L="1033" /S'
   StrLen $2 "$0"
   Strlen $1 "${SWITCH}"
   IntOp $1 $1 + 1
   StrCpy $0 "$0" $2 $1
 ;$0='1033" /S'
   Push "$0"
   Push '"'
   !insertmacro StrStr
   Pop $1
   StrLen $2 "$0"
   StrLen $3 "$1"
   IntOp $4 $2 - $3
   StrCpy $0 $0 $4 0
   Goto gpv_done_${LN}
 
   gpv_notquoted_${LN}:
   Push "$CMDLINE"
   Push "${SWITCH}"
   !insertmacro StrStr
   Pop $0
   StrCmp "$0" "" gpv_done_${LN}
 ;$0='/L="1033" /S'
   StrLen $2 "$0"
   Strlen $1 "${SWITCH}"
   StrCpy $0 "$0" $2 $1
 ;$0=1033 /S'
   Push "$0"
   Push ' '
   !insertmacro StrStr
   Pop $1
   StrLen $2 "$0"
   StrLen $3 "$1"
   IntOp $4 $2 - $3
   StrCpy $0 $0 $4 0
   Goto gpv_done_${LN}
 
   gpv_done_${LN}:
   StrCmp "$0" "" 0 +2
   StrCpy $0 "${DEFAULT}"
 
   Pop $4
   Pop $3
   Pop $2
   Pop $1
   Exch $0
   !undef LN
 !macroend
 
; And I had to modify StrStr a tiny bit.
; Possible upgrade switch the goto's to use ${__LINE__}
 
!macro STRSTR
  Exch $R1 ; st=haystack,old$R1, $R1=needle
  Exch    ; st=old$R1,haystack
  Exch $R2 ; st=old$R1,old$R2, $R2=haystack
  Push $R3
  Push $R4
  Push $R5
  StrLen $R3 $R1
  StrCpy $R4 0
  ; $R1=needle
  ; $R2=haystack
  ; $R3=len(needle)
  ; $R4=cnt
  ; $R5=tmp
 ;  loop;
    StrCpy $R5 $R2 $R3 $R4
    StrCmp $R5 $R1 +4
    StrCmp $R5 "" +3
    IntOp $R4 $R4 + 1
    Goto -4
 ;  done;
  StrCpy $R1 $R2 "" $R4
  Pop $R5
  Pop $R4
  Pop $R3
  Pop $R2
  Exch $R1
!macroend

!define GetCLIParameterValue "!insertmacro __GetCLIParameterValue"

;--------------------------------

!macro __GetRevision DestURL
  
    !define LN "${__LINE__}"
    StrCpy $1 ""
    
    !insertmacro __Download "silent" "Downloading version information..." "${DestURL}" "$PLUGINSDIR\temp.txt"
  
    Pop $R0
    StrCmp $R0 "OK" DetectRevision_${LN}

    ${DetailPrint} "Unable to obtain version information at this time."
    Goto SkipRevisionDetection_${LN}
    
    DetectRevision_${LN}:
    ClearErrors
    FileOpen $0 "$PLUGINSDIR\temp.txt" r
    IfErrors SkipRevisionDetection_${LN}
    FileRead $0 $1
    FileClose $0
    
    Push $1
    !insertmacro Trim
    Pop $1
  
    SkipRevisionDetection_${LN}:
    Delete "$PLUGINSDIR\temp.txt"
    
    Push $1
    
    !undef LN
!macroend

!macro TRIM

    Exch $R1 ; Original string
    Push $R2
 
Loop1_${LN}:
    StrCpy $R2 "$R1" 1
    StrCmp "$R2" " " TrimLeft_${LN}
    StrCmp "$R2" "$\r" TrimLeft_${LN}
    StrCmp "$R2" "$\n" TrimLeft_${LN}
    StrCmp "$R2" "$\t" TrimLeft_${LN}
    GoTo Loop2_${LN}
TrimLeft_${LN}:   
    StrCpy $R1 "$R1" "" 1
    Goto Loop1_${LN}
 
Loop2_${LN}:
    StrCpy $R2 "$R1" 1 -1
    StrCmp "$R2" " " TrimRight_${LN}
    StrCmp "$R2" "$\r" TrimRight_${LN}
    StrCmp "$R2" "$\n" TrimRight_${LN}
    StrCmp "$R2" "$\t" TrimRight_${LN}
    GoTo Done_${LN}
TrimRight_${LN}:  
    StrCpy $R1 "$R1" -1
    Goto Loop2_${LN}
 
Done_${LN}:
    Pop $R2
    Exch $R1
!macroend

!define GetRevision "!insertmacro __GetRevision"

;--------------------------------

!macro __MutexCheck _mutexname _outvar _handle 
    System::Call 'kernel32::CreateMutexA(i 0, i 0, t "${_mutexname}" ) i.r1 ?e' 
    StrCpy ${_handle} $1 
    Pop ${_outvar} 
!macroend 

!define MutexCheck "!insertmacro __MutexCheck"

;--------------------------------

!macro __MutexClose _handle 
    System::Call 'kernel32::CloseHandle(i ${_handle}) i.' 
!macroend 

!define MutexClose "!insertmacro __MutexClose"

;--------------------------------

; Push $filenamestring (e.g. 'c:\this\and\that\filename.htm')
; Push "\"
; Call StrSlash
; Pop $R0
; ;Now $R0 contains 'c:/this/and/that/filename.htm'
Function StrSlash
  Exch $R3 ; $R3 = needle ("\" or "/")
  Exch
  Exch $R1 ; $R1 = String to replacement in (haystack)
  Push $R2 ; Replaced haystack
  Push $R4 ; $R4 = not $R3 ("/" or "\")
  Push $R6
  Push $R7 ; Scratch reg
  StrCpy $R2 ""
  StrLen $R6 $R1
  StrCpy $R4 "\"
  StrCmp $R3 "/" loop
  StrCpy $R4 "/"  
loop:
  StrCpy $R7 $R1 1
  StrCpy $R1 $R1 $R6 1
  StrCmp $R7 $R3 found
  StrCpy $R2 "$R2$R7"
  StrCmp $R1 "" done loop
found:
  StrCpy $R2 "$R2$R4"
  StrCmp $R1 "" done loop
done:
  StrCpy $R3 $R2
  Pop $R7
  Pop $R6
  Pop $R4
  Pop $R2
  Pop $R1
  Exch $R3
FunctionEnd

!macro _StrSlashConstructor filenamestring 
  Push "${filenamestring}"
  Push "\"
  Call StrSlash
  Pop $0
!macroend
 
!define ConvertSlashes '!insertmacro "_StrSlashConstructor"'

;--------------------------------
